package com.atguigu.guli.service.trade.controller.api;

import com.atguigu.guli.service.result.R;
import com.atguigu.guli.service.trade.entity.Order;
import com.atguigu.guli.service.trade.entity.PayLog;
import com.atguigu.guli.service.trade.feign.EduCourseFeign;
import com.atguigu.guli.service.trade.service.OrderService;
import com.atguigu.guli.service.trade.service.PayLogService;
import com.atguigu.guli.utils.HttpClientUtils;
import com.atguigu.guli.utils.StreamUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/trade/weixin-pay")
public class ApiWXPayController {

    @Autowired
    OrderService orderService;
    @Autowired
    PayLogService payLogService;
    @Autowired
    EduCourseFeign eduCourseFeign;


    // 微信回调执行的方法
    @PostMapping("/notify")
    public String callBack(HttpServletRequest request) {
        //用来存响应内容的map
        Map returnMap = new HashMap();
        try {
            System.out.println("方法回调成功");
            // 获得回调成功的xml文档
            ServletInputStream is = request.getInputStream();
            //讲文档转换为UTF-8的字符串
            String resStr = StreamUtils.inputStream2String(is, "UTF-8");

            //判断签名是否正确
            boolean b = WXPayUtil.isSignatureValid(resStr, "atguigu3b0kn9g5vAtGuifHQH7X8rKCL");
            if (!b) {
                //返回微信一个错误
                returnMap.put("return_msg", "签名错误");
                return WXPayUtil.mapToXml(returnMap);
            }
            // 转换为map
            Map<String, String> map = WXPayUtil.xmlToMap(resStr);
            //判断返回的状态码是否为SUCCESS
            String returnCode = map.get("return_code");
            String resultCode = map.get("result_code");
            if (!"SUCCESS".equals(returnCode) || !"SUCCESS".equals(resultCode)) {
                //返回微信一个错误
                returnMap.put("return_msg", "业务错误");
                return WXPayUtil.mapToXml(returnMap);
            }
            //查询订单多少钱
            String outTradeNo = map.get("out_trade_no");
            LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper();
            wrapper.eq(Order::getOrderNo, outTradeNo);
            Order serviceOne = orderService.getOne(wrapper);
            //判断客户付款的金额
            long cashFee = Long.parseLong(map.get("cash_fee").toString());
            if (serviceOne.getTotalFee() != cashFee) {
                //返回微信一个错误
                returnMap.put("return_msg", "实付金额不一致");
                return WXPayUtil.mapToXml(returnMap);
            }
            //查看支付状态是不是未支付
            if (serviceOne.getStatus() == 0) {
                //修改状态
                serviceOne.setStatus(1);
                serviceOne.setPayType(1);
                orderService.updateById(serviceOne);
                //修改销量,要进行远程调用
                eduCourseFeign.update(serviceOne.getCourseId());
                // 返回微信正确响应
                returnMap.put("return_code", "SUCCESS");
                returnMap.put("return_msg", "OK");
            } else {// 订单已支付
                //课程已经更新过了
                returnMap.put("return_code", "FAIL");
                returnMap.put("return_msg", "已处理");
            }

            // 添加订单日志
            PayLog pay = new PayLog();
            pay.setAttr(resStr);   //订单的详细,也就是把微信返回的xnl文档转换成字符串的
            pay.setOrderNo(serviceOne.getOrderNo());  // 随机生成的订单号
            pay.setPayTime(serviceOne.getGmtCreate());  //支付时间也就是订单创建的时间
            pay.setPayType(1);  //支付的类型1是微信, 0是支付宝
            pay.setTotalFee(cashFee); //订单金额
            pay.setTradeState(serviceOne.getStatus().toString());  //订单是否已经支付 1支付 0 未支付
            pay.setTransactionId(map.get("transaction_id").toString());  //微信支付订单号
            //型数据库存入订单日志
            payLogService.save(pay);


            return WXPayUtil.mapToXml(returnMap);


        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("return_code", "FAIL");
            returnMap.put("return_msg", "出现异常");
            try {
                return WXPayUtil.mapToXml(returnMap);
            } catch (Exception exception) {
                exception.printStackTrace();
                throw new RuntimeException("究极异常");
            }
        }

    }


    @PostMapping("/auth/createNative/{orderId}")
    public R createNative(@PathVariable("orderId") String orderId, HttpServletRequest request) {
        try {
            //根据订单id查询商品信息
            Order order = orderService.getById(orderId);
            // 连接到微信给我提供的地址,用来生成二维码
            String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            HttpClientUtils client = new HttpClientUtils(url);
            //创建一个map,用来存数据,
            Map map = new HashMap<>();
            map.put("appid", "wxf913bfa3a2c7eeeb");  //微信支付分配的公众账号ID
            map.put("mch_id", "1543338551");   //微信支付分配的商户号
            map.put("nonce_str", WXPayUtil.generateNonceStr());  //生成随机字符串
            map.put("body", order.getCourseTitle());  //商品信息
            map.put("out_trade_no", order.getOrderNo()); //订单号
            map.put("total_fee", order.getTotalFee() + ""); //订单金额
            map.put("spbill_create_ip", request.getRemoteHost());  //获取客户端地址
            map.put("notify_url", "http://sh0225.free.idcfengye.com/api/trade/weixin-pay/notify");  //成功后回调的地址;
            map.put("trade_type", "NATIVE");  //交易类型(微信)

            //将数据构建成xml文档,同时生成签名添加到文档  key是秘钥 ; 用generateSignedXml方法,根据map集合的数据和秘钥生成签名
            String signedXml = WXPayUtil.generateSignedXml(map, "atguigu3b0kn9g5vAtGuifHQH7X8rKCL");
            client.setXmlParam(signedXml);  //将参数设置给客户端
            // 发送请求
            client.post();
            //发送请求后,会得到响应,得到返回参数
            String content = client.getContent();
            // 验证签名正不正确,这是为了防止别人恶意攻击篡改,签名就是验证的方式
            boolean sgin = WXPayUtil.isSignatureValid(content, "atguigu3b0kn9g5vAtGuifHQH7X8rKCL");
            if (!sgin) {
                //如果为false就是被人恶意攻击了,
                throw new RuntimeException("签名有异常,不正确");
            }
            //讲xml格式转为map;  因为想要获取微信返回的值,就必须转换map
            map = WXPayUtil.xmlToMap(content);

            String returnCode = map.get("return_code").toString();
            // 进行判断,返回有没有成功,  看文档写
            if (!"SUCCESS".equals(returnCode)) {
                throw new RuntimeException("微信返回结果有错 1111");
            }
            String resultCode = map.get("result_code").toString();
            if (!"SUCCESS".equals(resultCode)) {
                throw new RuntimeException("微信返回结果有错 22222");
            }
            // 走到这里就是微信返回成功,获取二维码地址
            String codeUrl = map.get("code_url").toString();
            return R.ok().data("code_url", codeUrl)
                    .data("courseId", order.getCourseId())
                    .data("out_trade_no", order.getOrderNo())
                    .data("orderId", order.getId())
                    .data("total_fee", order.getTotalFee());

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("走到最后拉,执行错误");
        }
    }
}
